#include <gtest/gtest.h>
#include <fstream>
#include <thread>
#include <chrono>

#include "utils_log.h"
#include "utils_init.h"
#include "common_init.h"
#include "nlohmann/json.hpp"
#include "media_snap.h"

namespace El {
namespace Media {

class MediaSnapTest : public ::testing::Test {
protected:
    static void SetUpTestSuite()
    {
        // 初始化基础库
        nlohmann::json config;
        config["log_file"] = "app.log";
        El::Utils::base_init(config);

        // 初始化配置
        config.clear();
        config["general"] = "app_config";
        config["default"] = "default_config";
        El::Common::common_init(config);
    }

    void SetUp() override {}

    void TearDown() override {}
};

TEST_F(MediaSnapTest, TestSnapBasicOperations)
{
    // 获取抓图实例
    auto &snap = Media::ISnap::GetInstance(0, MEDIA_VIDEO_ENC_STREAM_SNAPSHOT);

    // 创建用于同步的变量
    std::atomic<bool> snapReceived{false};
    std::condition_variable cv;
    std::mutex mtx;
    Media::MediaFramePtr receivedFrame;

    // 注册抓图回调
    auto callback = [&](const Media::MediaFramePtr &frame) {
        std::lock_guard<std::mutex> lock(mtx);
        snapReceived = true;
        receivedFrame = frame;
        cv.notify_one();
    };

    // 启动抓图模块
    ASSERT_TRUE(snap.Start()) << "Failed to start snap module";

    // 注册回调
    int32_t handle = snap.Register(callback);
    ASSERT_GE(handle, 0) << "Failed to register callback";

    // 触发手动抓图
    ASSERT_TRUE(snap.ManualSnap()) << "Failed to trigger manual snap";

    // 等待抓图完成或超时
    {
        std::unique_lock<std::mutex> lock(mtx);
        ASSERT_TRUE(cv.wait_for(lock, std::chrono::seconds(5), [&] { return snapReceived.load(); }))
            << "Timeout waiting for snapshot";
    }

    // 验证抓图结果
    ASSERT_TRUE(receivedFrame != nullptr) << "No frame received";
    EXPECT_EQ(receivedFrame->GetFrameType(), MEDIA_FRAME_JPEG) << "Unexpected frame type";
    EXPECT_GT(receivedFrame->GetLength(), 0) << "Frame has no data";

    // 停止抓图模块
    snap.Stop();
}

} // namespace Media
} // namespace El